﻿#region Includes
using System;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;

using OpenTK;
using GingerGL.Math;
#endregion

namespace GingerGL.Graphics
{
    //------------------------------------------------------------//
    /// <summary>
    /// Octree Class
    /// </summary>
    public class Octree : OctreeLeaf
    {
        //--------------------------------------------------------//
        #region Constructor
        /// <summary>
        /// Initializes a new instance of object
        /// </summary>
        public Octree() : base(new BoundingBox()) { }
        #endregion
        //--------------------------------------------------------//
        #region Methods
        /// <summary>
        /// Creates Bounding Box by Merge Child Bounding Boxes
        /// </summary>
        public void Bounds()
        {
            foreach (OctreeObject item in ContainedObjects)
                ContainerBox = BoundingBox.CreateMerged(ContainerBox, item.Bounds);
        }
        /// <summary>
        /// Add new node
        /// </summary>
        /// <param name="items">List of Otcree Objects to Add</param>
        public virtual void Add(IEnumerable<OctreeObject> items)
        {
            foreach (OctreeObject item in items)
                ContainedObjects.Add(item);
            Bounds();
            base.Distribute(0);
        }
        /// <summary>
        /// Add new node
        /// </summary>
        /// <param name="item">List of Otcree Objects to Add</param>
        public virtual void Add(OctreeObject item)
        {
            ContainedObjects.Add(item);
            Bounds();
            base.Distribute(0);
        }
        #endregion
        //--------------------------------------------------------//
        #region Example Overrides
        /*
        public override void ObjectsInFrustum(List<OctreeObject> objects, BoundingFrustum boundingFrustum)
        {
            bool useTree = true;
            if (useTree)
                base.ObjectsInFrustum(objects, boundingFrustum);
            else // brute force to see if our box in frustum works
                AddInFrustum(objects, boundingFrustum, this);
        }

        protected void AddInFrustum(List<OctreeObject> objects, BoundingFrustum boundingFrustum, OctreeLeaf leaf)
        {
            foreach (OctreeObject item in leaf.ContainedObjects)
            {
                if (boundingFrustum.Intersects(item.bounds))
                    objects.Add(item);
            }

            if (leaf.ChildLeaves != null)
            {
                foreach (OctreeLeaf child in leaf.ChildLeaves)
                    AddInFrustum(objects, boundingFrustum, child);
            }
        }

        public override void ObjectsInBoundingBox(List<OctreeObject> objects, BoundingBox box)
        {
            base.ObjectsInBoundingBox(objects, box);
        }

        public override void ObjectsInBoundingSphere(List<OctreeObject> objects, BoundingSphere sphere)
        {
            base.ObjectsInBoundingSphere(objects, sphere);
        }
        */
        #endregion
        //--------------------------------------------------------//
    }
    //------------------------------------------------------------//
}